﻿using Microsoft.Practices.EnterpriseLibrary.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TN_CMS.Domain.Abstract;
using TN_CMS.Domain.Entities;

namespace TN_CMS.Domain.Concrete
{
    public class EFNewsRepository : BaseRepository, INewsRepository
    {
        private EFDbContext context;

        public EFNewsRepository(EFDbContext context = null)
        {
            this.context = (context != null) ? context : new EFDbContext();
        }

        public IQueryable<News> News
        {
            get { return context.News; }
        }

        public IQueryable<News> GetList(out int total, int pageIndex = 0, int pageSize = 10, bool getInactive = true)
        {
            var entries = News
                .Where(a => a.IsActive == true || a.IsActive == !getInactive)
                .OrderBy(a => a.Id)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize);
            total = News
                .Count(a => a.IsActive == true || a.IsActive == !getInactive);
            return entries;
        }

        public List<News> GetList(int pageIndex, int pageSize, out int total, string orderClause, string whereClause)
        {

            var map = MapBuilder<News>
                .MapAllProperties()
                .DoNotMap(m => m.NewsGroups)
                .DoNotMap(m => m.CreatedByAdmin)
                .DoNotMap(m => m.UpdatedByAdmin)
                .Build();
            var parameters = new DbParameter[] { 
                    this._db.CreateParameter("PageIndex", pageIndex, DbType.Int32),
                    this._db.CreateParameter("PageSize", pageSize, DbType.Int32),
                    this._db.CreateParameter("TotalCounts", 0, DbType.Int32, ParameterDirection.Output),
                    this._db.CreateParameter("OrderClause", orderClause, DbType.String),
                    this._db.CreateParameter("WhereClause", whereClause, DbType.String)
                };
            var lst = this._db.Execute("SP_News_GetList", map, parameters).ToList();
            total = (int)parameters[2].Value;

            return lst;
        }

        public News GetDetail(int id, bool getInactive = true)
        {
            using (EFDbContext context = new EFDbContext())
            {
                var news = context.News.FirstOrDefault(a => a.Id == id && (a.IsActive == true || a.IsActive == !getInactive));

                //force EF load newsgroup
                news.NewsGroups.Select(a => a);

                return news;
            }
        }

        public int Save(News news, int actorId)
        {
            bool needToSave = false;
            if (news.Id <= 0)
            {
                news.CreatedBy = actorId;
                news.CreatedOn = DateTime.Now;
                context.News.Add(news);
                needToSave = true;
            }
            else
            {
                News dbEntry = context.News.FirstOrDefault(a => a.Id == news.Id);
                if (dbEntry != null)
                {
                    dbEntry.Title = news.Title;
                    dbEntry.Keywords = news.Keywords;
                    dbEntry.Summary = news.Summary;
                    dbEntry.Content = news.Content;
                    dbEntry.UpdatedOn = DateTime.Now;
                    dbEntry.UpdatedBy = actorId;
                    dbEntry.IsActive = news.IsActive;
                    needToSave = true;
                }
            }
            if (needToSave)
            {
                return context.SaveChanges();
            }
            return 0;
        }

        public void Delete(int[] ids)
        {
            bool needSaveChange = false;
            foreach (var id in ids)
            {
                News dbEntry = GetDetail(id);
                if (dbEntry != null)
                {
                    context.News.Remove(dbEntry);
                    needSaveChange = true;
                }
            }
            if (needSaveChange)
            {
                context.SaveChanges();
            }
        }

        public void UpdateActive(int[] arrId, bool isActive)
        {
            bool needToSave = false;
            foreach (var id in arrId)
            {
                News dbEntry = context.News.FirstOrDefault(a => a.Id == id);
                if (dbEntry != null)
                {
                    dbEntry.IsActive = isActive;
                    needToSave = true;
                }
            }
            if (needToSave)
            {
                context.SaveChanges();
            }
        }

    }
}
